package dk.dashboardFP.interactionElementFramwork {
	import dk.dashboardFP.utils.DisplayChainTools;

	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.IEventDispatcher;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;

	/**
	 * @author jk
	 */
	public class InteractionElementView extends Sprite {

		protected var _oIEHock : IInteractivElementHock;
		protected var _a_doLinkedDisplayObjects : Array;
		private var _a_oLinkedItems : Array;

		public function InteractionElementView() {
			registerDefaultInternalEvents();
			setupLinkedItemHandling();
			draw();
		}
		
		public function mouseUp() : void {
		}

		public function mouseDown() : void {
		}

		public function mouseOverSelected() : void {
		}
				
		public function mouseOutSelected() : void {
		}

		public function mouseOverDisabled() : void {
		}

		public function mouseOutDisabled() : void {
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// setup
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

		protected function draw() : void {
		}
		
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// linked view item
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

		private function setupLinkedItemHandling() : void {
			
			_a_doLinkedDisplayObjects=new Array();
			_a_oLinkedItems=new Array();
		}

		public function addLinkedDisplayObject(doLinkedItem:DisplayObject) : void {
			registerLinkedDO(doLinkedItem);
		}
		
		public function removeLinkedDisplayObject(doLinkedItem:DisplayObject) : void {
			_a_doLinkedDisplayObjects.splice(_a_doLinkedDisplayObjects.indexOf(doLinkedItem), 1);
			
			doLinkedItem.removeEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
			doLinkedItem.removeEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
		}

		protected function registerLinkedDO(doLinkedItem : DisplayObject) : void {
			
			_a_doLinkedDisplayObjects.push(doLinkedItem);
			
			//::
			// register do 
			doLinkedItem.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown, false, 0, true);
			doLinkedItem.addEventListener(MouseEvent.MOUSE_UP, onMouseUp, false, 0, true);
			
			doLinkedItem.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut, false, 0, true);
			doLinkedItem.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver, false, 0, true);
			
			doLinkedItem.addEventListener(MouseEvent.CLICK, onInternalClick, false, 0, true);
		}
		

		//::
		// related helpers 
				
		private function get_bMouseOutToRelated(relatedObject : DisplayObject) : Boolean {
			
			//::
			// check self 
			if (DisplayChainTools.get_bIsChildOf(relatedObject, this)) {
				return true;
			}
			
			//::
			// check do's
			for each (var doLinked : DisplayObject in _a_doLinkedDisplayObjects) {
				if (DisplayChainTools.get_bIsChildOf(relatedObject, doLinked)) {
					return true;
				}
			}
			return false;
		}
		
		private function get_bMouseOverToRelated(relatedObject : DisplayObject) : Boolean {
			
			//::
			// check self 
			if (DisplayChainTools.get_bIsChildOf(relatedObject, this)) {
				return true;
			}
			
			//::
			// check do's
			for each (var doLinked : DisplayObject in _a_doLinkedDisplayObjects) {
				if (DisplayChainTools.get_bIsChildOf(relatedObject, doLinked, true)) {
					return true;
				}
			}
			return false;
		}
		

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// register IEhock for acces to states
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

		final public function registerIEHock(oInteractivElementHock : IInteractivElementHock) : void {
			_oIEHock = oInteractivElementHock;
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// mouse interface
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

		public function mouseOver() : void {
		}

		public function mouseOut() : void {
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// selection state interface
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

		public function deSelect() : void {
		}

		public function select() : void {
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// focus
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

		public function focusIn() : void {
			addEventListener(KeyboardEvent.KEY_DOWN, onKeyDownInFocus, false, 0, true);
		}

		public function focusOut() : void {
			removeEventListener(KeyboardEvent.KEY_DOWN, onKeyDownInFocus);
		}	

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// disable enable
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		
		public function enable() : void {
		}
		
		public function disable() : void {
		}
		
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// keys while in focus
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

		protected function onKeyDownInFocus(event : KeyboardEvent) : void {
			dispatchEvent(new InteractionElementViewEvent(InteractionElementViewEvent.KEY_DOWN_VIEW, event));
		}	

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// internal handlers
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		
		private function onInternalClick(event : MouseEvent) : void {
			dispatchEvent(new InteractionElementViewEvent(InteractionElementViewEvent.CLICK_VIEW, event));
		}

		protected function registerDefaultInternalEvents() : void {
		
			addEventListener(MouseEvent.MOUSE_OVER, onMouseOver, false, 0, true);
			addEventListener(MouseEvent.MOUSE_OUT, onMouseOut, false, 0, true);

			addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown, false, 0, true);
			
			addEventListener(MouseEvent.CLICK, onInternalClick, false, 0, true);
		}
		
		protected function onMouseDown(event : MouseEvent) : void {
			stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp, false, 0, true);
			dispatchEvent(new InteractionElementViewEvent(InteractionElementViewEvent.MOUSE_DOWN_VIEW, event));
		}
		
		protected function onMouseUp(event : MouseEvent) : void {
			IEventDispatcher(event.target).removeEventListener(event.type, arguments["callee"]);
			dispatchEvent(new InteractionElementViewEvent(InteractionElementViewEvent.MOUSE_UP_VIEW, event));
		}

		protected function onMouseOut(event : MouseEvent) : void {
			if (!get_bMouseOutToRelated(event.relatedObject)) {
				dispatchEvent(new InteractionElementViewEvent(InteractionElementViewEvent.MOUSE_OUT_VIEW, event));
			}
		}

		protected function onMouseOver(event : MouseEvent) : void {
			if (!get_bMouseOverToRelated(event.relatedObject)) {
				dispatchEvent(new InteractionElementViewEvent(InteractionElementViewEvent.MOUSE_OVER_VIEW, event));
			}
		}
		
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// hide show
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		
		public function show() : void {
		}
		
		public function hide() : void {
		}
		
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// tween in out
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		
		public function tweenIn(nDelay : Number=0) : void {
		}
		
		public function tweenOut(nDelay : Number=0) : void {
		}
	}
}
